// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: jaewon

#include <boost/beast/version.hpp>
#include <glog/logging.h>

#include "coin2/base/request/http.h"
#include "coin2/base/request/root_certificates.h"

namespace ssl = boost::asio::ssl;  // from <boost/asio/ssl.hpp>
namespace request = coin2::base::request;

class Tester : private request::HttpsConnection::Handler {
 private:
  using HttpsConnection = coin2::base::request::HttpsConnection;

 public:
  Tester(boost::asio::io_context* io_ctx, ssl::context* ssl_ctx)
      : conn_(new request::HttpsConnection("naver.com", 443, this, io_ctx, ssl_ctx, "")) {
    conn_->Start();
  }

  void AsyncSend(const RequestType* req) { conn_->AsyncSend(req); }

  ~Tester() override = default;

 private:
  void OnConnected(std::weak_ptr<HttpsConnection> conn) override { LOG(INFO) << "OnConnected"; }

  void OnRequestSent(std::weak_ptr<HttpsConnection> conn, const RequestType* req) override {
    LOG(INFO) << "OnRequestSent: " << *req;
  }

  void OnResponseReceived(std::weak_ptr<HttpsConnection> conn, const ResponseType* res) override {
    LOG(INFO) << "OnResponseReceived: " << *res;
  }

  void OnError(std::weak_ptr<HttpsConnection> conn, boost::system::error_code ec) override {
    LOG(ERROR) << "OnError: " << ec.message();
  }

  std::shared_ptr<request::HttpsConnection> conn_;
};

int main(int argc, char* argv[]) {
  boost::asio::io_context io_ctx;
  ssl::context ssl_ctx{ssl::context::sslv23_client};
  request::LoadRootCertificates(&ssl_ctx);

  auto tester = new Tester(&io_ctx, &ssl_ctx);

  namespace http = boost::beast::http;
  request::HttpsConnection::RequestType req;
  const int version = 11;
  req.version(version);
  req.method(http::verb::get);
  req.keep_alive(true);
  req.target("/");
  req.set(http::field::host, "google.com");
  req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);

  tester->AsyncSend(&req);
  tester->AsyncSend(&req);
  tester->AsyncSend(&req);

  io_ctx.run();
  return 0;
}
